library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter is
  generic( bits : natural;
           bound : integer );
  port( clk, count, reset : in std_logic;
        o : out unsigned(0 to bits-1);
        carry : out std_logic );
end entity counter;

architecture behavioral of counter is
  
signal previous_count,next_count: unsigned(0 to bits-1) := (others => '0');

begin
  
  combinational_block: process(count,reset,previous_count) is
    variable tmp_count:unsigned(0 to bits-1):= (others => '0');
   -- variable one_count:unsigned(0 to bits-1) := (bits-1 => '1',others => '0');
    variable one_count:unsigned(0 to 1) := "01";
	 variable bound_binary:unsigned(0 to bits-1) := to_unsigned(bound,bits);
    variable all_zeros:unsigned(0 to bits-1):= (others => '0');
    variable wrap_around :std_logic := '0';

    begin
                  
      tmp_count := previous_count;

      if reset='1' then
        tmp_count := (others => '0');
        wrap_around := '0';

      elsif count='1' then
          tmp_count:=tmp_count + 1;    
          if tmp_count = bound_binary then
            tmp_count := (others => '0');
            wrap_around := '1';            
          end if;          
      end if;
      
           
      if tmp_count = all_zeros and wrap_around = '1' then
        carry <='1';
        wrap_around := '0';
      else
        carry <='0';
      end if;
      if tmp_count < bound_binary then 
	 o <= tmp_count;
         next_count <= tmp_count;
      else
	 o <= (others => '0');
	 next_count <= (others => '0');
      end if;
	    
  end process combinational_block;
  
  sequential_block: process(clk,reset) is
  begin
    if reset = '1' then
      previous_count <= (others => '0');
    elsif rising_edge(clk) then
      previous_count <= next_count;
    end if;
  end process sequential_block;
end architecture behavioral;
--------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity counter_testbench is
  port( clk, count, reset : in std_logic;
        o : out unsigned(0 to 3);
        carry : out std_logic );
end entity counter_testbench;

architecture counter_testbench_behavioral of counter_testbench is
  
  signal carry0,c_in1_trigger : std_logic := '0';
  signal deci_tick_op : unsigned(0 to 3) := (others => '0');
  
begin
  
  counter_instance0 : entity work.counter(behavioral) generic map(4,10) port map(clk,count,reset,deci_tick_op,carry0);
  counter_instance1 : entity work.counter(behavioral) generic map(4,10) port map(clk,carry0,reset,o,carry);

end architecture counter_testbench_behavioral;
